define(function(require, exports, module) {

var $ = require('$');
var Widget = require('widget');
var Handlebars = require('handlebars');
var moment = require('moment');
var Confirm = require('confirm');
var Tips = require('tips');
var Alert = require('alert');

var util = require('../util');
var io = require('../io');
var Form = require('../form/form');
var FormData = require('../form/data');

var DateRange = require('./daterange');

var transparentSrc = util.transparentSrc;

/**
 * 分页查询核心
 *
 * @class Core
 * @param  {[type]} )
 * @return {[type]}   [description]
 */
var Core = Widget.extend({
  defaults: {
    element: '#J_Search',
    container: null,
    // 时间选项
    dateCfg: {
      // 时间显示的位置 left or right
      opens: 'left',
      startTimeName: 'startTime',
      endTimeName: 'endTime'
    },
    // 表单选项
    formCfg: {
      // 隐藏域
      hiddens: {
        // startTime: '',
        // endTime: '',
        sortOrder: 'desc',
        sortColumn: '',
        pageNo: 1
      },
      data: {
        layout: 'inline',
        buttons: null,
        groups: []
      },
      xhr: false
    },
    gridElement: null,
    // handlebars helpers
    gridHelpers: {
      fthumb: function(url, type, affix) {
        var classError = 'thumb-error',
            className = 'thumb-160x120 thumb-160x120-' + (type || 'default'),
            onError = 'this.src=\'' + transparentSrc + '\';this.classList.add(\'' + classError + '\')"';

        if (url && typeof affix === 'string') {
          url += affix;
        }

        if (!url) {
          className += ' ' + classError;
        }

        return '<img class="' + className + '"' +
            ' onerror="' + onError + '"' +
            ' src="' + (url || transparentSrc) + '">';
      },
      fdate: function(createTime) {
        return createTime ? moment(createTime).format('YYYY-MM-DD') : '';
      },
      ellipsis: function(val, size) {
        if (!val) {
          return '';
        } else {
          var len = val.length;
          val = len <= size ? val : ('<span title="' + val +'">' + val.slice(0, size - 1) + '&hellip;' + '</span>');
          return val;
        }
      }
    },
    keepHistory: true,
    // 列表请求地址
    url: null,
    // 删除行请求地址
    delUrl: null,
    // 删除时的提示信息
    delMsg: '确定删除？',
    // 删除的请求参数,默认为id
    delKey: 'docId',
    delegates: {
      'click :submit': function () {
        if (this.form) {
          this.form.$('[name=pageNo]').val(1);
        }
      },
      'submit': 'onSearch',
      'click [data-role=del]': 'delRow'
    }
  },

  setup: function() {
    this.render();

    if (!this.option('url')) {
      throw new Error('请设置 url');
    }

    this.initForm();
    this.initDate();

    this.initGrid();
  },

  initForm: function () {
    var self = this,
        formCfg,
        dateCfg,
        groups,
        hiddens,
        buttons,
        key;

    // 兼容写在 ftl 里的 form
    self.formElement = self.$('form');

    if (!self.formElement.length) {
      formCfg = self.option('formCfg');

      if (self.option('keepHistory')) {
        formCfg.values = util.queryToJson(window.location.hash.substring(1));
      }

      formCfg.container = self.element;

      // 添加默认隐藏域
      groups = formCfg.data.groups;
      hiddens = formCfg.hiddens,
      buttons = formCfg.buttons;

      // 添加 date 隐藏域
      dateCfg = self.option('dateCfg');
      if (!dateCfg.disabled) {
        hiddens[dateCfg.startTimeName] = '';
        hiddens[dateCfg.endTimeName] = '';
      }

      for (key in hiddens) {
        groups.unshift({
          hidden: true,
          colspan: null,
          attrs: {
            type: 'hidden',
            name: key,
            value: hiddens[key]
          }
        });
      }

      if (buttons) {
        buttons.forEach(function (button) {
          groups.unshift(button);
        });
      }

      self.form = new Form(formCfg);
      self.formElement = self.form.element;

      self.form.on('valid', function () {
        self.refresh();
      });
    }

    self.formElement.addClass('grid-head clearfix');
  },

  initGrid: function () {
    this.gridElement = $(this.option('gridElement'));
    if (!this.gridElement.length) {
      this.gridElement = $('<div/>').insertAfter(this.formElement);
    }

    this.gridElement.addClass('grid-body');

    this.initHelper();
    this.renderGrid();
  },

  delRow: function(e) {
    var self = this;

    if (!self.option('delUrl')) {
      throw new Error('请设置 delUrl');
    }

    new Confirm({
      content: self.option('delMsg')
    }).submit(function () {
      var param = {};

      param[self.option('delKey')] = e.currentTarget.dataset.id;
      param.docStatus = '00';

      io.post(self.option('delUrl'), param, function () {
          new Tips({
            content: '删除成功！'
          });
          // TODO: 改成 FORM SUBMIT
          self.refresh();
        });
    });
  },

  onSearch: function(e) {
    if (e) {
      e.preventDefault();
    }

    if (!this.form) {
      this.renderGrid();
    }

    return false;
  },

  refresh: function() {
  },

  initHelper: function () {
    var helpers = this.option('gridHelpers'), p;

    for (p in helpers) {
      Handlebars.registerHelper(p , helpers[p]);
    }
  },

  renderGrid: function() {
  },

  postData: function() {
    var postData = this.option('postData');
    if (typeof postData === 'function') {
      return postData.call(this, this.getParams());
    } else {
      return this.getParams();
    }
  },

  getParams: function() {
    var formData = this.formData = new FormData(this.$('form').prop('elements'));
    if (this.option('keepHistory')) {
      window.location.hash = formData.paramify(true);
    }
    return formData.toJSON();
  },

  setParam: function(key, value) {
    if (this.formData) {
      this.formData.set(key, value);
    }
  },

  getParam: function(key) {
    return this.formData ? this.formData.get(key) : '';
  },

  /**
   * 创建时间
   *
   * @method initDate
   * @return {[type]} [description]
   */
  initDate: function() {
    var dateCfg = this.option('dateCfg');

    if (dateCfg.disabled) {
      return;
    }

    dateCfg.container = this.$(':submit');
    dateCfg.insert = function() {
      this.container.before(this.element);
    };

    this.dateRange = new DateRange(dateCfg);
  },

  destroy: function (callback) {
    if (callback) {
      return this.on('destroy', callback);
    }

    this.dateRange && this.dateRange.destroy();

    Core.superclass.destroy.apply(this);
  }

});

return Core;
});
